#ifndef LIBPLATTCP
#define LIBPLATTCP

/***
*	The objects and methods contained here, define and implement a cross platform interface for networking using the TCP protocol
*	As well as dealing with the most common error cases.
*/

#include <winsock.h>
#include <string>
#include <sstream>
#include <map>
#ifndef EAGAIN
#define EAGAIN WSAEWOULDBLOCK
#endif

namespace Platinum{
	namespace Net{
		namespace TCP{
			
			/**
			*	TCP::Connection objects contain a socket and address objects
			*	They are used for tracking TCP Sockets and associating them with the remote addresses
			*/

			struct Connection{
				SOCKET Socket;				
				struct sockaddr_in Addr;
				Connection();
				~Connection();
			};

			/**
			*	The TCP::Initialize function initializes a Connection object 
			*	Initialization includes misc work such as setting address family and setting the socket to non-blocking
			*/
			bool Initialize(Connection* MyConn);

			/**
			*	TCP::Bind binds the connection to a given port
			*/
			bool Bind(Connection* MyConn, int iPort);

			void SetBlocking(Connection* MyConn, bool state);
			/**
			*	TCP::Connect establishes an out going connection to a given IP on a given port
			*/
			bool Connect(Connection* MyConn,std::string IP,int iPort);


			/**
			*	TCP::Listen listens to a given Connection waiting for an incoming connection
			*	It will not block and returns a new Connection object if there is a waiting connection 
			*	or it will return the original Connection object if there was no waiting connection
			*/
			Connection* Listen(Connection* MyConn);

			/**
			*	TCP::Send will send data to a given Connection
			*	It will thow an exception if you pass it an empty string or if the data could not be sent,
			*	or if the connection was closesocketd
			*/
			bool Send(Connection* MyConn, std::string Data);

			/**
			*	TCP::Recv will recieve data from a connection and return a string containing that data.
			*	It will throw an exception if the connection was closed.
			*/
			std::string Recv(Connection* MyConn);
		}
	}
}
#endif

